// 数字枚举
// enum Direction {
//   Up = 1,
//   Down,
//   Left,
//   Right
// }
// console.log(Direction.Down) // 2

// enum Direction {
//   Up,
//   Down,
//   Left,
//   Right
// }
// console.log(Direction.Down) // 1

// enum ResponseOne {
//   No = 0,
//   Yes = 1
// }

// function respond(recipient: string, message: ResponseOne): void {
//   // ...
// }

// respond('Princess Caroline', ResponseOne.Yes)

// enum E {
//   A = getSomeValue(),
//   B
// }

// 字符串枚举
// enum Direction {
//   Up = 'Up',
//   Down = 'Down',
//   Left = 'Left',
//   Right = 'Right'
// }

// 异构枚举
// enum BooleanLikeHeterogeneousEnum {
//   No = 0,
//   Yes = 'YES'
// }

// enum E { x }
// console.log(E.x) // 0

// enum E1 { X, Y, Z }
// console.log(E1.X, E1.Y, E1.Z) // 0 1 2

// enum FileAccess {
//   None,
//   Read = 1 << 1,
//   Write = 1 << 2,
//   ReadWrite = Read | Write,
//   G = '123'.length
// }
// console.log(FileAccess.Read)

// enum ShapeKind {
//   Circle,
//   Square
// }

// interface Circle {
//   kind: ShapeKind.Circle
//   radius: number
// }

// interface Square {
//   kind: ShapeKind.Square
//   sideLength: number
// }

// let c: Circle = {
//   kind: ShapeKind.Circle,
//   radius: 100
// }

// enum E {
//   Foo,
//   Bar
// }

// function f(x: E) {
//   if (x !== E.Foo || x !== E.Bar)
// }

// 运行时枚举
// enum E {
//   X, Y, Z
// }
// function f(obj: { X: number }) {
//   return obj.X
// }

// console.log(f(E))

// 反向映射
// enum Enum {
//   A
// }
// let a = Enum.A
// let nameOfA = Enum[a]
// console.log(nameOfA) // A

// const 枚举
// const enum Enum {
//   A = 1,
//   B = A * 2
// }

// const enum Directions {
//   Up,
//   Down,
//   Left,
//   Right
// }

// let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]
// console.log(directions) // [ 0, 1, 2, 3 ]

// 外部枚举
// declare enum Enum {
//   A = 1,
//   B,
//   C = 2
// }


// 类型推论
// let x = 3

// let y = [0, 1, null]

// 上下文类型
// window.onmousedown = function(mouseEvent) {
//   console.log(mouseEvent.button)
// }
